#include "points.hpp"

/// vector class operator overloads
vec& vec::operator =(const vec& v) {
	x = v.x;
	y = v.y;
	return *this;
}

vec& vec::operator +=(const vec& v) {
	x += v.x;
	y += v.y;
	return *this;
}

vec& vec::operator +=(float k) {
	x += k;
	y += k;
	return *this;
}

vec& vec::operator -=(float k) {
	x -= k;
	y -= k;
	return *this;
}

vec& vec::operator -=(const vec& v) {
	x -= v.x;
	y -= v.y;
	return *this;
}

vec& vec::operator *=(float k) {
	x *= k;
	y *= k;
	return *this;
}

vec& vec::operator /=(float k) {
	x /= k;
	y /= k;
	return *this;
}

vec vec::operator -() {
	return vec(-x, -y);
}

vec vec::operator +(const vec& v) {
	vec result(*this);
	result += v;
	return result;
}

vec vec::operator -(const vec& v) {
	vec result(*this);
	result -= v;
	return result;
}

vec vec::operator +(float k) {
	vec result(*this);
	result += k;
	return result;
}

vec vec::operator -(float k) {
	vec result(*this);
	result -= k;
	return result;
}

vec vec::operator *(float k) {
	vec result(*this);
	result *= k;
	return result;
}

vec vec::operator /(float k) {
	vec result(*this);
	result /= k;
	return result;
}

vec& vec::operator ()(float xx, float yy) {
	x = xx;
	y = yy;
	return *this;
}

vec operator *(float k, const vec& v) {
    vec rez = v;
    return rez * k;
}


//---------------- comparing ----------------------
//------ return 1st bit 1 if left y > right y -----
//------ return 2nd bit 1 if left x > right x -----
short vec::operator ==(const vec& k) const {
	short p = 0;
	p += (x > k.x ? 1 : 0) << 1;
	p += (y > k.y ? 1 : 0) << 0;
	return p;
}

float vec::len() {
	return sqrt(x*x + y*y);
}

float vec::arct() {
    if(x < 0) {
        if(y < 0) {
            return atan(y/x) - PI;
        }
        else {
            return atan(y/x) + PI;
        }
    }
    else {
        return atan(y/x);
    }
}

// -------------- wire methods -------------------
void wire::length(vec a, vec b) {
	len = b - a;
}

void wire::length() {
	len = pe->pos - ps->pos;
}

// ----------- funcs to read from file -----------

void getpoints(point* &p, uint &size){
	FILE* imput = fopen("imputdot.txt", "r");
	fscanf(imput, "points: %u\n", &size);
	p = new point [size];
	for (uint i = 0; i < size; i ++) {
		fscanf(imput, "(%f, %f) (%f, %f) (%f, %f) m%f\n",
		&p[i].pos.x, &p[i].pos.y, &p[i].vel.x, &p[i].vel.y,
		&p[i].fo.x, &p[i].fo.y, &p[i].mass);
	}
	fclose (imput);
}

void getwires(wire* &w, uint &wsize, point* p, uint &size){
	FILE* imput = fopen("wiring.txt", "r");
	fscanf(imput, "wires: %u\n", &wsize);
	w = new wire[wsize];
	uint s, e;
	float k;
	for (uint i = 0; i < wsize; i++) {
		fscanf(imput, "%f: %u - %u\n", &k, &s, &e);
		if(s != e){
			if(s > e){
				s ^= e;
				e ^= s;
				s ^= e;
			}
			w[i].koof = k;
			w[i].ps = &p[s-1];
			w[i].pe = &p[e-1];
			w[i].length(w[i].ps->pos, w[i].pe->pos);
			w[i].rest = w[i].len.len();
		}
	}
	fclose (imput);
}
